package com.scs.application.interceptor;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.scs.application.consts.GlobalConsts;
import com.scs.application.core.utils.UtilWebsocket;
import com.scs.application.modules.base.util.CommonService;
import com.scs.application.modules.cfg.sync.ParamSyncService;
import com.scs.application.modules.fsd.service.StationService;
import com.scs.application.modules.print.sync.PrintTemplateSyncService;
import com.scs.application.modules.sys.adapter.DataViewAdapter;
import com.scs.application.modules.sys.entity.ScheduleJob;
import com.scs.application.modules.sys.properties.SystemProperties;
import com.scs.application.modules.sys.service.InitDataService;
import com.scs.application.modules.sys.service.ScheduleJobService;
import com.scs.application.modules.sys.service.impl.SystemCommonServiceImpl;
import com.scs.application.modules.sys.sync.DictSyncService;
import com.scs.application.modules.sys.sync.FlowSyncService;
import com.scs.application.modules.sys.sync.SerialRuleSyncService;
import com.scs.application.modules.sys.utils.UtilDatabase;
import com.scs.application.modules.thirdparty.request.view.his.HisReqServiceImpl;
import com.scs.application.modules.upgrade.service.SystemUpgradeService;
import com.scs.application.modules.wm.enums.WorkOrderType;
import com.scs.application.modules.wm.service.StockService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.concurrent.CompletableFuture;

/**
 * 继承Application接口后项目启动时会按照执行顺序执行run方法
 * 通过设置Order的value来指定执行的顺序
 */
@Component
@Configuration
@Order(value = 1)
@Slf4j
public class StartService implements InitializingBean, ApplicationRunner {

    @Autowired
    @Lazy
    private SystemUpgradeService systemUpgradeService;

    @Autowired
    @Lazy
    private SystemCommonServiceImpl systemCommonService;

    @Autowired
    @Lazy
    private InitDataService initDataService;

    @Autowired
    @Lazy
    private StationService stationService;

    @Autowired
    @Lazy
    private DataViewAdapter dataViewAdapter;
    @Autowired
    @Lazy
    private com.scs.application.modules.base.service.MatrCategoryService matrCategoryService;

    @Autowired
    @Lazy
    private StockService stockService;
    @Value("${upgrade-database.inactive:true}")
    String upgradeFlag;
    @Value("${init-data.inactive:true}")
    String autoInitFlag;
    @Value("${spring.profiles.active}")
    private String env;

    @Autowired
    private ScheduleJobService scheduleJobService;

    @Autowired
    private SystemProperties systemProperties;

    @Autowired
    private FlowSyncService flowSyncService;

    @Autowired
    private DictSyncService dictSyncService;

    @Autowired
    private ParamSyncService paramSyncService;

    @Autowired
    private SerialRuleSyncService serialRuleSyncService;

    @Autowired
    private PrintTemplateSyncService printTemplateSyncService;

    @Value("${spring.datasource.dynamic.datasource.dbhis.driver-class-name}")
    private String driverClassNameHis;
    @Value("${spring.datasource.dynamic.datasource.dbhis.username}")
    private String usernameHis;

    @Value("${spring.datasource.dynamic.datasource.dbhis.url}")
    private String urlHis;

    @Value("${spring.datasource.dynamic.datasource.dbhis.password}")
    private String passwordHis;


    public  DriverManagerDataSource getDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(driverClassNameHis);
        dataSource.setUrl(urlHis);
        dataSource.setUsername(usernameHis);
        dataSource.setPassword(passwordHis);
        return dataSource;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        log.info("-- 不执行初始化数据");
        Date date1;
        Date date2;
        try {
//            if (!Boolean.parseBoolean(upgradeFlag)) {
//                // ==数据结构升级==
//                date1 = DateUtils.now();
//                log.info("-- 数据结构升级启动于：" + DateUtils.format(date1, "yyyy-MM-dd hh:mm:ss"));
//
//                systemUpgradeService.upgradeDatabase("");
//                date2 = DateUtils.now();
//                log.info("-- 数据结构升级完成于：" + DateUtils.format(date2, "yyyy-MM-dd hh:mm:ss")
//                        + ",耗时：" + DateUtils.formatTime(date2.getTime() - date1.getTime()));
//            }
            // ==初始化数据==
//            if (!Boolean.parseBoolean(autoInitFlag)) {
//                date1 = DateUtils.now();
//                initDataService.execute(null);
//                date2 = DateUtils.now();
//                log.info("-- 执行初始化数据完成于：" + DateUtils.format(date1, "yyyy-MM-dd hh:mm:ss")
//                        + ",耗时：" + DateUtils.formatTime(date2.getTime() - date1.getTime()));
//            } else {
//                log.info("-- 不执行初始化数据");
//            }
//
//            systemUpgradeService.upgradeMenu();
//            stationService.initOnlineStatus();
            WorkOrderType.init();

            HisReqServiceImpl.jdbcTemplate =  new JdbcTemplate(getDataSource());
        }catch (Exception e){
            log.error("StartServiceError",e);
            throw e;
        }

    }



    @Override
    /**
     * 当程序启动完毕后执行，不影响程序启动速度
     * 问题记录：同步打印模板因为Field.format字段长度不够，抛出异常，但是没有事务控制，导致只有部分数据同步成功
    */
    public void run(ApplicationArguments args) throws Exception {

        //从缓存获取session
        UtilWebsocket.getCache();

        CommonService.cacheSerialOwner();


        /**
         * 非个人环境，启用定时任务
         * 将数据库中的job加入执行，查询未启用的
         */
        scheduleJobService.update(Wrappers.<ScheduleJob>update().set("status_execution", GlobalConsts.JobStatusExecution.NOT_RUN));
        if (!env.equalsIgnoreCase("dev")) {
            scheduleJobService.startAll(false);
        }

        //同步字典类型
//        CompletableFuture.supplyAsync(() -> {
//            dictSyncService.syncDictType();
//            return "同步字典类型 ";
//        });
        //同步流程
//        CompletableFuture.supplyAsync(() -> {
//            flowSyncService.syncFlow();
//            return "同步流程";
//        });
        //同步参数
//        CompletableFuture.supplyAsync(() -> {
//            paramSyncService.syncParameters();
//            return "同步参数";
//        });
        //同步编号规则
//        CompletableFuture.supplyAsync(() -> {
//            serialRuleSyncService.syncSerialRule();
//            return "同步编号规则";
//        });
        //同步打印模板
//        CompletableFuture.supplyAsync(() -> {
//            printTemplateSyncService.syncPrintTemplate();
//            return "同步打印模板";
//        });
        //同步参数
        CompletableFuture.supplyAsync(() -> {
            paramSyncService.syncParameters();
            return "同步参数";
        });

        //数据视图缓存
        CommonService.cacheDataview(null);

        CommonService.cachereport(null);

        //耗材表库存数量
        CompletableFuture.supplyAsync(() -> {
            CommonService.updateMatrStockNums(null,null);
            return "耗材表库存数量 ";
        });

        //耗材表库存数量
//        CompletableFuture.supplyAsync(() -> {
//            return matrCategoryService.repairData();
//        });

        //0库存
        CompletableFuture.supplyAsync(() -> {
            stockService.updateOeAddStockZero();
            return "0库存 ";
        });

        //刷新临时表数据
        CompletableFuture.supplyAsync(() -> {
            CommonService.reportTempTable(null,false);
            return "刷新临时表数据 ";
        });

        //必要基础数据缓存
        CompletableFuture.supplyAsync(() -> {
            //科室缓存
            CommonService.cacheDept();
            return "必要基础数据缓存 ";
        });

        //初始化表字段关系
        UtilDatabase.initDbTableColumnMap();
        UtilDatabase.initDbBackupTableColumnMap(null);
    }
}
